#include <CH559.H>
#ifndef MY_USB_H
#define MY_USB_H
/* Macro Extension */
#define USE_IN_8BITS_MCU

typedef struct _USB_CLASS_REQ
{
    /**
     * @brief bmRequestType BitMap
     * @param D7 Dir 0:Host->Device,1:Device->Host
     * @param D6_D5 CommandType 00:StandardReq,01:ClassReq,10:User-Reserved,11:Reserved
     * @param D4_D0 RecipientType 0000:Device,0001:Interface,0010:EndpPoint,Other:Reserved
     * @note D7=1,D6_D5=01,D4_D1=0001,(0xA1)
     */
    UINT8 bRequestType;
    UINT8 bRequest;
    UINT8 wValueL;
    UINT8 wValueH;
    /**
     * @brief wIndex
     * @param wIndex Target interface number
     * 
     */
    UINT8 wIndexL;
    UINT8 wIndexH;
    /**
     * @brief wLength
     * @param wLength Size of data block (bytes)
     * 
     */
    UINT8 wLengthL;
    UINT8 wLengthH;
    UINT8 *p_data;
}USB_CLASS_REQ, *pUSB_CLASS_REQ;
#ifdef USE_IN_8BITS_MCU
typedef USB_CLASS_REQ xdata *PXUSB_CLASS_REQ;
#endif

typedef struct _USB_HEADER_FUNCTIONAL_DESCR
{
    UINT8 bFunctionalLength;
    UINT8 bDescriptorType;
    UINT8 bDescriptorSubType;
    UINT8 bcdCDCL;
    UINT8 bcdCDCH;
}USB_HEADER_FUNCTIONAL_DESCR, *pUSB_HEADER_FUNCTIONAL_DESCR;

#ifdef USE_IN_8BITS_MCU
typedef USB_HEADER_FUNCTIONAL_DESCR xdata *PXUSB_HEADER_FUNCTIONAL_DESCR;
#endif

typedef struct _USB_CALL_MANAGEMENT_FUNCTIONAL_DESCR
{
    UINT8 bFunctionalLength;
    UINT8 bDescriptorType;
    UINT8 bDescriptorSubType;
    UINT8 bmCapabilities;
    UINT8 bDataInterface;
}USB_CALL_MANAGEMENT_FUNCTIONAL_DESCR, *pUSB_CALL_MANAGEMENT_FUNCTIONAL_DESCR;

#ifdef USE_IN_8BITS_MCU
typedef USB_CALL_MANAGEMENT_FUNCTIONAL_DESCR xdata *PXUSB_CALL_MANAGEMENT_FUNCTIONAL_DESCR;
#endif

typedef struct _USB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR
{
    UINT8 bFunctionalLength;
    UINT8 bDescriptorType;
    UINT8 bDescriptorSubType;
    UINT8 bCapabilities;
}USB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR, *pUSB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR;

#ifdef USE_IN_8BITS_MCU
typedef USB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR xdata *PXUSB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR;
#endif

typedef struct _USB_UNION_FUNCTIONAL_DESCR
{
    UINT8 bFunctionalLength;
    UINT8 bDescriptorType;
    UINT8 bDescriptorSubType;

    /**
     * @brief bSlaveInterface
     * @param bslaveInterface CDC data class interface number
     * 
     */
    UINT8 bMasterInterface;

     /**
     * @brief bMasterInterface
     * @param bMasterInterface CDC control interface number
     * 
     */
    UINT8 bSlaveInterface;
}USB_UNION_FUNCTIONAL_DESCR,*pUSB_UNION_FUNCTIONAL_DESCR;

typedef struct _USB_CONF_DESCR_FULL
{
    USB_CFG_DESCR ConfigHeader;
    USB_ITF_DESCR itf0_control;
    USB_HEADER_FUNCTIONAL_DESCR header_func;
    USB_CALL_MANAGEMENT_FUNCTIONAL_DESCR call_manage_func;
    USB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR abst_func;
    USB_UNION_FUNCTIONAL_DESCR union_func;
    USB_ENDP_DESCR itf0_endpoint;
    USB_ITF_DESCR itf1_data;
    USB_ENDP_DESCR itf1_endpoint_in;
    USB_ENDP_DESCR itf1_endpoint_out;
}USB_CONF_DESCR_FULL;

#define EP0_MAX_SIZE 8

#define USB_SET_LINE_CODING 0x20
#define USB_GET_LINE_CODING 0x21
#define USB_SET_CONTROL_LINE_STATE 0x22

struct _line_coding
{
    /**
     * @brief dwDTERate
     * @param dwDTERatex Serial Baud,bits per second.(little endian)
     */
    UINT8 dwDTERate0;
    UINT8 dwDTERate1;
    UINT8 dwDTERate2;
    UINT8 dwDTERate3;

    /**
     * @brief bCharFormat
     * @param bCharFormat StopBits 00:1bit, 01:1.5bits, 02:2bits
     * 
     */
    UINT8 bCharFormat;

    /**
     * @brief bParityType
     * @param bParityType ParityBit 00:None, 01:Odd, 02:Even, 03:Space
     * 
     */
    UINT8 bParityType;

    /**
     * @brief bDataBits
     * @param bDataBits 5,6,7,8 or 16Bits
     * 
     */
    UINT8 bDataBits;
};

#define USB_SETUP_PACKET ((PXUSB_SETUP_REQ)Ep0Buffer)

static UINT8 usb_config;

const UINT8 LANGUAGE_ID[] = {0x04,0x03,0x09,0x04};

const UINT8 DEVICE_SN[] = {22,USB_DESCR_TYP_STRING, 'C','h','a','r','_','X'};

const UINT8 DEVICE_MANUFACTURER_SN[] = {80, USB_DESCR_TYP_STRING,'C'};

const UINT8 PRODUCT_SN[] = {98,USB_DESCR_TYP_STRING,'C'};

const UINT8 usb_device_descriptor[]=
{
sizeof(USB_DEV_DESCR),USB_DESCR_TYP_DEVICE, 0x10,0x01,0x02,0x00,0x00,EP0_MAX_SIZE, 0x88,0x88,0x01,0x00,0x10,0x01,0x01,0x02,0x03,0x01
};

const UINT8 usb_configuration_descriptor[] = 
{
//Configuration0 Descriptor
sizeof(USB_CFG_DESCR),USB_DESCR_TYP_CONFIG,  sizeof(USB_CONF_DESCR_FULL),0x00, 0x02,0x01,0x00,0xA0,0xC8,

//Interface0 Descriptor(CDC)
sizeof(USB_ITF_DESCR),USB_DESCR_TYP_INTERF,0x00,0x00,0x01,0x02,0x02,0x01,0x00,
//Interface0 Functional descriptor header
sizeof(USB_HEADER_FUNCTIONAL_DESCR),USB_DESCR_TYP_CS_INTF,0x00,0x10,0x01, /* CDC bcd11 */
//Interface0 Functional descriptor call management
sizeof(USB_CALL_MANAGEMENT_FUNCTIONAL_DESCR),USB_DESCR_TYP_CS_INTF,0x01,0x00,0x00,
//Interface0 Functional abstract control
sizeof(USB_ABSTRACT_CONTROL_MANAGEMENT_FUNCTIONAL_DESCR),USB_DESCR_TYP_CS_INTF,0x02,0x02, /* D1: Support SetLineCoding GetLineCoding SetControlLineState and SerialState notification */
//Interface0 Functional union
sizeof(USB_UNION_FUNCTIONAL_DESCR),USB_DESCR_TYP_CS_INTF,0x06,0x00,0x01,
//Interface0 EndPoint Descriptor(Interrupt-IN)
sizeof(USB_ENDP_DESCR),USB_DESCR_TYP_ENDP,0x81,0x03,0x10,0x00,0x01,

//Interface1 Descriptor(DATA-Class)
sizeof(USB_ITF_DESCR),USB_DESCR_TYP_INTERF,0x01,0x00,0x02,0x0A,0x00,0x00,0x00,
//Interface1 EndPoint Descripor(Bluk-IN)
sizeof(USB_ENDP_DESCR),USB_DESCR_TYP_ENDP,0x82,0x02,0x40,0x00,0x0A,
//Interface1 EndPoint Descriptor(Bluk-OUT)
sizeof(USB_ENDP_DESCR),USB_DESCR_TYP_ENDP,0x02,0x02,0x40,0x00,0x0A,
};

//const UINT8 usb_configuration_descriptor[] = {
//0x09,0x02,0x43,0x00, 0x02,0x01,0x00,0xA0,0xC8,
//0x09,0x04,0x00,0x00,0x01,0x02,0x02,0x01,0x00,
//0x05,0x24,0x00,0x10,0x01, 
//0x05,0x24,0x01,0x00,0x00,
//0x04,0x24,0x02,0x02,
//0x05,0x24,0x06,0x00,0x01,
//0x07,0x05,0x81,0x03,0x10,0x00,0x01,
//0x09,0x04,0x01,0x00,0x02,0x0A,0x00,0x00,0x00,
//0x07,0x05,0x82,0x02,0x40,0x00,0x0A,
//0x07,0x05,0x02,0x02,0x40,0x00,0x0A
//};

#endif
